﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System;
namespace KFGame
{
    public class USBHook
    {
        public static USBHook m_hInstance;

        //建立钩子
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
        //移除钩子
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);
        private const int WH_KEYBOARD_LL = 13;
        private const int WM_KEYDOWN = 0x0100;
        private static LowLevelKeyboardProc _proc = HookCallback;
        private static IntPtr _hookID = IntPtr.Zero;


        int lenNow = 0;
        int vkCodeLast = 0;
        private List<string> _result = new List<string>();  // 返回结果集 

        public static USBHook Instantiation()
        {
            if (m_hInstance == null)
            {
                  UnityEngine.Debug.Log("usb qrcode :start Instantiation");

                m_hInstance = new USBHook();
                _hookID = SetHook(_proc);
            }
            return m_hInstance;
        }


        public static string Read()
        {
            string s = string.Join("", USBHook.m_hInstance._result.ToArray());
            // if(s!=null && s!="")
            // UnityEngine.Debug.Log("usb qrcode read:"+ s);

            if (s.EndsWith("\r\n"))
            { 
                USBHook.m_hInstance.ClearResult();
                return s.Trim();
            }
            return "";
        }

        public void ClearResult()
        {
            USBHook.m_hInstance._result.Clear();
        }

        private static IntPtr SetHook(LowLevelKeyboardProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
            }
        }
        private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);

        private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
           // UnityEngine.Debug.Log("back");
          //  bool isShift = false;

            if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
            {

                int vkCode = Marshal.ReadInt32(lParam);
                //   UnityEngine.Debug.Log("ASCII:" + vkCode);

                if (vkCode >= 65 && vkCode <= 90)
                    vkCode = vkCode + 32;//处理为小写字母

                if (USBHook.m_hInstance.vkCodeLast == 160)
                {
                    if (vkCode >= 48 && vkCode <= 57)
                    {
                        if (vkCode == 48)
                            vkCode = 41;//)
                        else if (vkCode == 49)
                            vkCode = 33; //!
                        else if (vkCode == 50)
                            vkCode = 64;// @
                        else if (vkCode == 51)
                            vkCode = 35;//#
                        else if (vkCode == 52)
                            vkCode = 36;//$
                        else if (vkCode == 53)
                            vkCode = 37;//%
                        else if (vkCode == 54)
                            vkCode = 94;//^
                        else if (vkCode == 55)
                            vkCode = 38;//&
                        else if (vkCode == 56)
                            vkCode = 42;//*
                        else if (vkCode == 57)
                            vkCode = 40;//)
                        else if (vkCode == 189)
                            vkCode = 95;//_
                        else if (vkCode == 187)
                            vkCode = 43;//+
                    }
                    else if (vkCode >= 97 && vkCode <= 122)
                        vkCode = vkCode - 32;//为大写字母

                    if (vkCode == 186)//:
                    {
                        vkCode = 58;
                    }
                    else if (vkCode == 187)
                        vkCode = 43;//+
                    else if (vkCode == 189)
                        vkCode = 95;//-
                    else if (vkCode == 190)
                        vkCode = 62;//>
                    else if (vkCode == 191)
                        vkCode = 63;//?
                    else if (vkCode == 219)
                        vkCode = 123;//{
                    else if (vkCode == 220)
                        vkCode = 124;//|
                    else if (vkCode == 221)
                        vkCode = 125;//}
                }

                if (vkCode == 186)// ;
                {
                    vkCode = 59;
                }
                if (vkCode == 187)// =
                {
                    vkCode = 61;
                }
                if (vkCode == 189)// -
                {
                    vkCode = 45;
                }
                if (vkCode == 190)//.
                {
                    vkCode = 46;
                }
                if (vkCode == 191)// /
                {
                    vkCode = 47;
                }
                if (vkCode == 219)
                    vkCode = 91;//[
                if (vkCode == 220)
                    vkCode = 92;//\
                if (vkCode == 220)
                    vkCode = 93;//]

                if (vkCode == 109)// 数字键-
                {
                    vkCode = 45;
                }

                if (vkCode == 13)
                {
                    USBHook.m_hInstance._result.Add("\r\n");
                }


                if (vkCode != 160 && vkCode != 13 && vkCode != 40)
                {
                    USBHook.m_hInstance.lenNow++;

                    string alpha = Convert.ToChar(vkCode).ToString();
                    USBHook.m_hInstance._result.Add(alpha);
                }

                USBHook.m_hInstance.vkCodeLast = vkCode;
            }
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }

        public static void Quit()
        {
            UnhookWindowsHookEx(_hookID);
        }
    }
}

